package com.study.example.gameserver.module.scene.bt.node;

import com.sparrow.common.ai.behaviortree.BehaviorContext;
import com.sparrow.common.ai.behaviortree.def.BTNodeStatus;
import com.sparrow.common.ai.behaviortree.node.impl.ActionNode;
import com.sparrow.common.aoi.util.MapUtil;
import com.sparrow.common.map.Position;
import com.study.example.gameserver.module.scene.entity.impl.Monster;
import com.study.example.gameserver.module.player.entity.Player;

import java.util.List;

/**
 * 行为节点：按路径追击移动（逐点行走）
 * <p>
 * 特点：
 * - 每次 tick 按速度推进一段距离；
 * - 若路径走完则返回 SUCCESS；
 * - 若目标偏移较大（>1m）则返回 FAILURE；
 * - 否则持续返回 RUNNING。
 */
public class ChaseRoad extends ActionNode {

    /** 接近目标点的判定阈值（米） */
    private static final float REACH_THRESHOLD = 0.2f;

    @Override
    public BTNodeStatus tick(BehaviorContext context, long now, long delta) {
        Monster monster = context.getOwner();
        if (monster == null) {
            return BTNodeStatus.FAILURE;
        }

        List<Position> roads = monster.getRoads();
        int roadIndex = monster.getRoadIndex();
        if (roads == null || roads.isEmpty() || roadIndex >= roads.size()) {
            return finish(monster);
        }

        Player targetPlayer = context.get("ChaseTarget", Player.class);
        if (targetPlayer == null || targetPlayer.getPos() == null) {
            return BTNodeStatus.FAILURE;
        }

        Position finalTargetPos = roads.get(roads.size() - 1);
        // 目标已移动较远，说明路径过期
        if (MapUtil.getDistance(finalTargetPos, targetPlayer.getPos()) > 1.0f) {
            return BTNodeStatus.FAILURE;
        }

        Position currentPos = monster.getPos();
        Position nextWaypoint = roads.get(roadIndex);
        if (currentPos == null || nextWaypoint == null) {
            return BTNodeStatus.FAILURE;
        }

        float distance = MapUtil.getDistance(currentPos, nextWaypoint);
        if (distance <= REACH_THRESHOLD) {
            // 已接近当前路点 → 进入下一个
            monster.setRoadIndex(roadIndex + 1);
            monster.updateAngle();
            return (monster.getRoadIndex() >= roads.size()) ? finish(monster) : BTNodeStatus.RUNNING;
        }

        // 移动推进
        float deltaTime = delta / 1000f;
        float step = monster.getSpeed() * deltaTime;

        if (step >= distance) {
            // 一步跨过目标点
            monster.setPos(new Position(nextWaypoint.getX(), currentPos.getY(), nextWaypoint.getZ()));
            monster.setRoadIndex(roadIndex + 1);
            monster.updateAngle();
            return (monster.getRoadIndex() >= roads.size()) ? finish(monster) : BTNodeStatus.RUNNING;
        }

        // 按方向推进一小步
        float dx = nextWaypoint.getX() - currentPos.getX();
        float dz = nextWaypoint.getZ() - currentPos.getZ();
        float factor = step / distance;

        float newX = currentPos.getX() + dx * factor;
        float newZ = currentPos.getZ() + dz * factor;
        monster.setPos(new Position(newX, currentPos.getY(), newZ));

        return BTNodeStatus.RUNNING;
    }

    /**
     * 结束移动
     */
    private BTNodeStatus finish(Monster monster) {
        monster.setRoads(null);
        monster.setRoadIndex(0);
        return BTNodeStatus.SUCCESS;
    }
}
